<!--
 * Copyright © 2023
 * @Author: zhangxiang
 * @Date: 2023-03-14 16:07:07
 * @LastEditors: zhangxiang
 * @LastEditTime: 2023-11-04 10:12:14
 * @Description:
 *
-->

<template>
  <MyContainer class="policy-deployment-container">
    <MyHeader class="header">
      <span class="name">应用名称</span>
      <el-input
        v-model="applicationName"
        style="width: 200px; margin-left: 10px; margin-right: 20px"
        size="medium"
        class="input"
        placeholder="请输入应用名称"
        @keyup.enter.native="queryClick"
      />
      <span class="name">微服务名称</span>
      <el-input
        v-model="serviceName"
        style="width: 200px; margin-left: 10px; margin-right: 20px"
        size="medium"
        class="input"
        placeholder="请输入微服务名称"
        @keyup.enter.native="queryClick"
      />
      <el-button
        size="medium"
        type="primary"
        @click="queryClick"
      >查 询</el-button>
      <el-button
        size="medium"
        type="primary"
        plain=""
        @click="resetClick"
      >重 置</el-button>
    </MyHeader>

    <MyMain class="main">
      <div v-for="(item, index) in list" :key="index" :class="['service']">
        <div class="top">
          <div class="title">
            {{ item.applicationName }} - {{ item.svcName }}
          </div>
          <div v-if="isGPU(item.scheduleStrategy)" class="arch">GPU</div>
          <!-- 状态 -->
          <template>
            <el-tag
              v-if="item.status === '0'"
              class="status"
              type="info"
              effect="dark"
              size="small"
            >初始</el-tag>
            <el-tag
              v-else-if="item.status === '1'"
              class="status"
              type="success"
              effect="dark"
              size="small"
              style="cursor: pointer"
              @click="viewDeploymentStage(item)"
            >运行中</el-tag>
            <el-tag
              v-else-if="item.status === '2'"
              class="status"
              size="small"
              style="cursor: pointer"
              @click="viewDeploymentStage(item)"
            >已暂停</el-tag>
            <el-tag
              v-else-if="item.status === '3'"
              class="status"
              type="warning"
              effect="dark"
              size="small"
              style="cursor: pointer"
              @click="viewDeploymentStage(item)"
            >启动中</el-tag>
            <el-tag
              v-else-if="item.status === '4'"
              class="status"
              type="danger"
              effect="dark"
              size="small"
            >删除中</el-tag>
            <el-tag
              v-else-if="item.status === '5'"
              class="status"
              type="info"
              effect="plain"
              size="small"
            >已结束</el-tag>
            <el-tag
              v-else-if="item.status === '7'"
              class="status"
              type="danger"
              size="small"
              style="cursor: pointer"
              @click="viewDeploymentStage(item)"
            >失败</el-tag>
          </template>
          <!-- 操作 -->
          <div class="options">
            <!-- 不在重新部署中 -->
            <template v-if="!item.inRedeploy">
              <el-button
                v-if="item.category == 'AI' && item.status === '1'"
                style="padding: 5px 10px"
                size="mini"
                type="primary"
                icon="el-icon-video-pause"
                @click="switchStatus(item)"
              >暂停服务</el-button>
              <el-button
                v-if="item.category == 'AI' && item.status === '2'"
                style="padding: 5px 10px"
                size="mini"
                type="primary"
                icon="el-icon-video-play"
                @click="switchStatus(item)"
              >恢复服务</el-button>
              <el-button
                v-if="item.category == 'AI' && item.status === '1'"
                style="padding: 5px 10px"
                size="mini"
                type="primary"
                icon="el-icon-refresh"
                @click="redeployClick(index)"
              >重新部署</el-button>
              <el-button
                v-if="item.status !== '4'"
                style="padding: 5px 10px"
                size="mini"
                type="primary"
                icon="el-icon-delete"
                @click="deleteMicSvc(item)"
              >删除</el-button>
            </template>
            <template v-else>
              <el-button
                v-if="item.category == 'AI' && item.status === '1'"
                style="padding: 4px 10px"
                size="mini"
                type="text"
                @click="redeployCancel(index)"
              >取消</el-button>
              <el-button
                v-if="item.category == 'AI' && item.status === '1'"
                style="padding: 5px 10px"
                size="mini"
                type="primary"
                :loading="item.redeployBtnLoading"
                @click="redeployConfirm(index)"
              >确定</el-button>
            </template>
          </div>
        </div>
        <div class="basic">
          <div class="basic-item">
            <div class="subtitle">大小</div>
            <div class="subcontent">{{ item.size }}</div>
          </div>
          <div class="basic-item">
            <div class="subtitle">上传者</div>
            <div class="subcontent">{{ item.provider }}</div>
          </div>
          <div class="basic-item">
            <div class="subtitle">当前状态</div>
            <template>
              <el-tag
                v-if="item.status === '0'"
                type="info"
                effect="dark"
                size="small"
              >初始</el-tag>
              <el-tag
                v-else-if="item.status === '1'"
                type="success"
                effect="dark"
                size="small"
                style="cursor: pointer"
                @click="viewDeploymentStage(item)"
              >运行中</el-tag>
              <el-tag
                v-else-if="item.status === '2'"
                size="small"
                style="cursor: pointer"
                @click="viewDeploymentStage(item)"
              >已暂停</el-tag>
              <el-tag
                v-else-if="item.status === '3'"
                type="warning"
                effect="dark"
                size="small"
                style="cursor: pointer"
                @click="viewDeploymentStage(item)"
              >启动中</el-tag>
              <el-tag
                v-else-if="item.status === '4'"
                type="danger"
                effect="dark"
                size="small"
              >删除中</el-tag>
              <el-tag
                v-else-if="item.status === '5'"
                type="info"
                effect="plain"
                size="small"
              >已结束</el-tag>
              <el-tag
                v-else-if="item.status === '7'"
                type="danger"
                size="small"
                style="cursor: pointer"
                @click="viewDeploymentStage(item)"
              >失败</el-tag>
            </template>
          </div>
          <div class="basic-item special">
            <div class="subtitle">访问路径</div>
            <template v-if="Array.isArray(item.paths) && item.paths.length > 0">
              <div class="path">{{ item.paths[0] }}</div>
              <el-button
                size="mini"
                type="text"
                @click="copyPath(item.paths[0])"
              >复制</el-button>
            </template>
          </div>
        </div>
        <div class="policys">
          <div class="schedule">
            <div class="column scene">
              <div class="subtitle">服务模型</div>
              <div
                v-if="
                  itemScheduleStrategy(item) &&
                    itemScheduleStrategy(item).businessScene
                "
                class="subcontent"
              >
                {{
                  itemScheduleStrategy(item).businessScene.svcCategory +
                    " - " +
                    itemScheduleStrategy(item).businessScene.svcType
                }}
              </div>
              <el-button
                v-if="item.inRedeploy"
                size="mini"
                type="text"
                style="height: 20px; padding: 0; margin-left: 20px"
                @click="scheduleStrategyClick(item, index)"
              >修改</el-button>
            </div>
            <div class="column strategy">
              <div class="subtitle">调度编排</div>
              <div v-if="itemScheduleStrategy(item)" class="sublist">
                <template
                  v-for="(strategy, strategyIndex) in scheduleStrategyAll"
                >
                  <div
                    v-if="
                      strategyIndex !== 0 &&
                        itemScheduleStrategy(item)[strategy.value]
                    "
                    :key="'line-' + strategyIndex"
                    class="line"
                  ></div>
                  <div
                    v-if="itemScheduleStrategy(item)[strategy.value]"
                    :key="'subitem-' + strategyIndex"
                    class="subitem"
                  >
                    {{ itemScheduleStrategy(item)[strategy.value].policy }}
                    {{ itemScheduleStrategy(item)[strategy.value].percent }}%
                  </div>
                </template>
              </div>
            </div>
          </div>
          <div class="pline"></div>
          <div class="scale">
            <div class="column">
              <div class="subtitle">弹性扩缩</div>
              <div class="subcontent">
                {{ scaleStrategysText(item.scaleStrategy) }}
              </div>
              <el-button
                v-if="cannotModifyScale(item)"
                size="mini"
                type="text"
                @click="scaleStrategyClick(item, index)"
              >修改</el-button>
            </div>
            <div class="column wrap">
              <div class="subtitle">虚机扩缩容</div>
              <template v-for="(cluster, clusterIndex) in item.clusterAndAlgs">
                <div :key="'clusterName-' + clusterIndex" class="subcontent">
                  {{ cluster.clusterName }}
                </div>
                <div
                  :key="'vmScaleStragetyStr-' + clusterIndex"
                  class="subcontent content2"
                >
                  {{ cluster.vmScaleStragetyStr }}
                </div>
              </template>
            </div>
            <div class="column">
              <template
                v-for="(sitem, sindex) in scaleStrategyExceptVM(
                  item.scaleStrategy
                )"
              >
                <div :key="sindex" class="subtitle">
                  {{ sitem.name }}
                </div>
                <div :key="sitem.id" :class="['subcontent', 'content2']">
                  {{ sitem.text }}
                </div>
              </template>
            </div>
          </div>
        </div>
        <!-- <div class="intelligent">
          <div v-if="item.scheduleStrategy" class="left">
            <div class="title">调度智能决策配置</div>
            <div class="column">
              <div class="subtitle">调度智能策略</div>
              <el-radio-group
                v-model="item.scheduleStrategy.intelligentScheduleActive"
                class="radios"
                :disabled="item.status !== '2'"
                @input="intelligentScheduleActiveChange($event, item)"
              >
                <el-radio :label="0">关闭</el-radio>
                <el-radio :label="1">开启</el-radio>
              </el-radio-group>
            </div>
            <div
              v-if="item.scheduleStrategy.intelligentScheduleActive == 1"
              class="column"
            >
              <div class="subtitle">智能决策周期</div>
              <el-radio-group
                v-model="item.scheduleStrategy.intelligentDuration"
                class="radios"
                :disabled="item.status !== '2'"
                @input="intelligentDurationChange($event, item)"
              >
                <el-radio :label="3">3个月</el-radio>
                <el-radio :label="6">6个月</el-radio>
                <el-radio :label="12">1年</el-radio>
              </el-radio-group>
            </div>
          </div>
          <div class="pline"></div>
          <div class="right">
            <div class="title">调度智能决策结果</div>
            <el-table
              class="decision-table"
              :data="item.intelligentHistoryVOS || []"
              header-cell-class-name="listHeaderCell"
              :header-cell-style="{ color: '#696969' }"
            >
              <el-table-column
                prop="currentClusters"
                label="当前云商：集群"
                min-width="140"
                show-overflow-tooltip=""
              >
                <template slot-scope="scope">
                  <span
                    v-for="(cluster, clusterIndex) in scope.row.currentClusters"
                    :key="clusterIndex"
                  >
                    {{ clusterIndex == 0 ? "" : "/" }}
                    {{ getCloudProviderChn(cluster.provider) }}：{{
                      cluster.clusterName
                    }}
                  </span>
                </template>
              </el-table-column>
              <el-table-column
                prop="suggestClusters"
                label="优化建议云商：集群"
                min-width="150"
                show-overflow-tooltip=""
              >
                <template slot-scope="scope">
                  <span
                    v-for="(cluster, clusterIndex) in scope.row.suggestClusters"
                    :key="clusterIndex"
                  >
                    {{ clusterIndex == 0 ? "" : "/" }}
                    {{ getCloudProviderChn(cluster.provider) }}：{{
                      cluster.clusterName
                    }}
                  </span>
                </template>
              </el-table-column>
              <el-table-column
                prop="activeTime"
                label="优化时间"
                width="150"
                show-overflow-tooltip=""
              />
              <el-table-column prop="status" label="决策结果" width="100" />
              <el-table-column label="操作" width="90">
                <template slot-scope="scope">
                  <el-button
                    type="danger"
                    size="mini"
                    style="height: 22px; padding: 0 10px"
                    @click="clearIntelligentDecision(scope.row)"
                  >清除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </div> -->
        <div class="clusters">
          <div class="title">部署集群</div>
          <div class="cluster-wrapper">
            <div
              v-for="(cluster, clusterIndex) in item.clusterAndAlgs"
              :key="clusterIndex"
              :class="['cluster', !cluster.deployed ? 'unable' : '']"
              @click="clusterClick(index, cluster, clusterIndex)"
            >
              <div :class="['img-wrapper', !cluster.deployed ? 'unable' : '']">
                <img class="img" :src="cluster.providerImg" alt="" />
              </div>
              <div class="name provider">{{ cluster.providerChn }}</div>
              <div class="name">{{ cluster.clusterName }}</div>
            </div>
          </div>
          <el-button
            v-if="item.clusterAndAlgs && item.clusterAndAlgs.length > 0"
            class="expand"
            style="padding: 5px 10px"
            size="mini"
            type="primary"
            :icon="
              item.activeAlgIndex >= 0
                ? 'el-icon-arrow-up'
                : 'el-icon-arrow-down'
            "
            @click="clusterExpandClick(index)"
          >详细信息</el-button>
        </div>
        <AlgAnalyseResults
          v-if="item.activeAlgIndex >= 0"
          class="alg-results-wrapper"
          :info="item.clusterAndAlgs[item.activeAlgIndex].algResults"
          :service-id="item.svcId"
          :can-choose="false"
        />
      </div>
      <el-row type="flex" justify="end" style="margin-top: 30px">
        <el-pagination
          background
          layout="total, sizes, prev, pager, next"
          :page-sizes="[3, 6, 10]"
          :page-size="pageSize"
          :current-page.sync="pageNum"
          :total="totalSize"
          @current-change="changePage"
          @size-change="sizeChange"
        />
      </el-row>
    </MyMain>
    <!-- 微服务部署进度 -->
    <ServiceDeploymentDialog
      v-if="showSvcDeploymentDialog"
      :show.sync="showSvcDeploymentDialog"
      :micro-service="svcDeploymentDialogInfo"
    />
    <!-- 调度策略修改弹窗 -->
    <ScheduleStrategyDialogV2
      v-if="showScheduleDialog"
      :show.sync="showScheduleDialog"
      :is-edit="true"
      :simple="true"
      :info="scheduleDialogInfo"
      @simple-callback="simpleEditScheduleCallback"
    />
    <!-- 扩缩容策略修改弹窗 -->
    <ScaleStrategyDialogV2
      v-if="showScaleDialog"
      :show.sync="showScaleDialog"
      :is-edit="true"
      :can-edit-scalevm="false"
      :info="scaleDialogInfo"
      :choosed-clusters="userChooseClusters"
      @edit-success="editScaleSuccessCallback"
    />
  </MyContainer>
</template>

<script>
import MyContainer from '@/components/Layout/MyContainer.vue'
import MyHeader from '@/components/Layout/MyHeader.vue'
import MyMain from '@/components/Layout/MyMain.vue'
import {
  STRATEGY_SCALE_TYPE,
  getClusterProviderChn,
  getCloudProviderImg,
  GPU_BUSINESS_SCENE,
  UNSCALE_BUSINESS_SCENES,
  STRATEGY_SCHEDULE_V2
} from '@/utils/cnap/constant'
import {
  getMicroServiceList,
  microServiceOperation,
  addScheduleStrategy,
  updateStrategyIntelligent,
  deleteIntelligentDecision,
  getClusterScaleInfos
} from '@/api/cnap/app-service'
import AlgAnalyseResults from '../components/AlgAnalyseResults.vue'
import ServiceDeploymentDialog from '../policy/ServiceDeploymentDialog.vue'
import ScheduleStrategyDialogV2 from '../components/ScheduleStrategyDialogV2.vue'
import ScaleStrategyDialogV2 from '../components/ScaleStrategyDialogV2.vue'

let abortController = null

export default {
  name: 'PolicyDeployment',
  components: {
    MyContainer,
    MyHeader,
    MyMain,
    AlgAnalyseResults,
    ServiceDeploymentDialog,
    ScheduleStrategyDialogV2,
    ScaleStrategyDialogV2
  },
  data() {
    return {
      timerRefresh: null, // 刷新-计时器
      scaleStrategyNoneStr: 'policy":"none',
      applicationName: null, // 应用名
      serviceName: null, // 服务名
      pageSize: 3, // 页size
      pageNum: 1, // 页码
      totalSize: 0, // 总数
      loading: false, // 加载
      list: [], // 列表
      scheduleStrategyAll: STRATEGY_SCHEDULE_V2,
      showSvcDeploymentDialog: false, // 显示部署进度弹窗
      svcDeploymentDialogInfo: {}, // 部署进弹窗数据
      showScheduleDialog: false, // 显示调度弹窗
      scheduleDialogIndex: -1, // 调度弹窗index
      scheduleDialogInfo: {}, // 调度弹窗数据
      userChooseClusters: [],
      showScaleDialog: false, // 显示扩缩容弹窗
      scaleDialogInfo: {}, // 扩缩容弹窗数据
      scaleClustersTimer: null
    }
  },
  computed: {},
  beforeDestroy() {
    this.clearTimerAndReq()
  },
  created() {
    this.initPageData() // 加载数据
  },
  methods: {
    /**
     * @description: 清空定时器
     * @return {*}
     */
    clearTimerAndReq() {
      if (this.scaleClustersTimer) {
        // 清空 集群扩缩容查询 定时器
        clearTimeout(this.scaleClustersTimer)
        this.scaleClustersTimer = null
      }
      if (this.timerRefresh) {
        // 清空定时器
        clearTimeout(this.timerRefresh)
        this.timerRefresh = null
      }
      // 取消请求
      abortController && abortController.abort()
    },
    /**
     * @description: 可以修改扩缩容
     * @param {*} item
     * @return {*}
     */
    cannotModifyScale(item) {
      if (
        item.status === '2' &&
        item.scheduleStrategy &&
        item.scheduleStrategy.businessScene
      ) {
        return !UNSCALE_BUSINESS_SCENES.includes(
          item.scheduleStrategy.businessScene.svcType
        )
      }
      return false
    },
    /**
     * @description: 是GPU
     * @param {*} scheduleStrategy
     * @return {*}
     */
    isGPU(scheduleStrategy) {
      return (
        scheduleStrategy &&
        scheduleStrategy.businessScene &&
        scheduleStrategy.businessScene.svcType === GPU_BUSINESS_SCENE
      )
    },
    /**
     * @description: 展开/收起
     * @param {*} index
     * @return {*}
     */
    clusterExpandClick(index) {
      if (this.list[index].activeAlgIndex < 0) {
        this.list[index].activeAlgIndex = 0
      } else {
        this.list[index].activeAlgIndex = -1
      }
    },
    /**
     * @description: 部署集群点击
     * @param {*} index
     * @param {*} clusterIndex
     * @return {*}
     */
    clusterClick(index, cluster, clusterIndex) {
      if (!cluster.deployed) {
        return
      }
      this.list[index].activeAlgIndex = clusterIndex
    },
    /**
     * @description: 修改扩缩容策略成功回调
     * @return {*}
     */
    editScaleSuccessCallback() {
      this.getList() // 刷新数据
    },
    /**
     * @description: 修改扩缩容策略
     * @param {*} item
     * @param {*} index
     * @return {*}
     */
    scaleStrategyClick(item, index) {
      this.scaleDialogInfo = {
        serviceId: item.svcId,
        serviceName: item.svcName,
        serviceStatus: item.status,
        category: item.category, // 类别
        scaleStrategy: item.scaleStrategy // 策略
      }
      this.computeUserChooseClusters(this.list[index])
      this.showScaleDialog = true // 显示弹窗
    },
    /**
     * @description: 计算用户准备编辑微服务的云商-集群
     * @param {*} svcInfo
     * @return {*}
     */
    computeUserChooseClusters(svcInfo) {
      if (!(svcInfo && Array.isArray(svcInfo.clusterInfos))) {
        return []
      }
      const arr = []
      for (const element of svcInfo.clusterInfos) {
        if (
          Array.isArray(element.clusterNames) &&
          element.clusterNames.length > 0 &&
          element.clusterNames[0]
        ) {
          const clusterName = element.clusterNames.join('/')
          const providerName = this.getCloudProviderChn(element.manufacturer)
          arr.push({
            clusterName: clusterName,
            providerName: providerName
          })
        }
      }
      this.userChooseClusters = arr
    },
    /**
     * @description: 查看部署进度
     * @param {*} item
     * @return {*}
     */
    viewDeploymentStage(item) {
      this.svcDeploymentDialogInfo = JSON.parse(JSON.stringify(item))
      this.showSvcDeploymentDialog = true // 显示弹窗
    },
    /**
     * @description: 清除智能决策结果
     * @param {*} row
     * @return {*}
     */
    clearIntelligentDecision(row) {
      deleteIntelligentDecision(row.id).then((res) => {
        this.$message.success('清除成功')
        this.getList()
      })
    },
    /**
     * @description: 云商中文
     * @param {*} en
     * @return {*}
     */
    getCloudProviderChn(en) {
      return getClusterProviderChn(this.$store.state.app.cloudVendors, en)
    },
    /**
     * @description: 智能决策周期修改
     * @param {*} val
     * @param {*} item
     * @return {*}
     */
    intelligentDurationChange(val, item) {
      updateStrategyIntelligent({
        active: item.scheduleStrategy.intelligentScheduleActive,
        duration: val,
        svcId: item.svcId
      })
    },
    /**
     * @description: 调度智能决策修改
     * @param {*} val
     * @param {*} item
     * @return {*}
     */
    intelligentScheduleActiveChange(val, item) {
      updateStrategyIntelligent({
        active: val,
        duration: item.scheduleStrategy.intelligentDuration,
        svcId: item.svcId
      })
    },
    /**
     * @description: 扩缩容策略类别名称
     * @param {*} name
     * @return {*}
     */
    getScaleTypeName(name) {
      if (Object.keys(STRATEGY_SCALE_TYPE).includes(name)) {
        return STRATEGY_SCALE_TYPE[name].label
      }
      return ''
    },
    /**
     * @description: 除了 虚机扩缩容 之外的 扩缩容策略
     * @param {*} scaleStrategy
     * @return {*}
     */
    scaleStrategyExceptVM(scaleStrategy) {
      const arr = []
      Object.keys(STRATEGY_SCALE_TYPE).forEach((key) => {
        if (key !== 'vm') {
          // 除了虚机扩缩容
          let text = '不配置'
          if (Array.isArray(scaleStrategy)) {
            const findItem = scaleStrategy.find((item) => {
              return item.scaleType === key
            })
            text =
              findItem &&
              !findItem.strategyParam.includes(this.scaleStrategyNoneStr)
                ? '配置'
                : '不配置'
          }
          arr.push({
            name: STRATEGY_SCALE_TYPE[key].label,
            text: text
          })
        }
      })
      return arr
    },
    /**
     * @description: 扩缩容策略拼接
     * @return {*}
     */
    scaleStrategysText(scaleStrategy) {
      const arr = []
      if (Array.isArray(scaleStrategy)) {
        scaleStrategy.forEach((element) => {
          if (element.strategyName !== '不配置') {
            arr.push(element.strategyName)
          }
        })
      }
      return arr.length === 0 ? '无' : arr.join(' / ')
    },
    /**
     * @description: 复制路径
     * @param {*} path
     * @return {*}
     */
    copyPath(path) {
      this.$copyText(path)
        .then((res) => {
          this.$message.success('复制成功')
        })
        .catch((err) => {
          console.log(err)
          this.$message.error('复制失败')
        })
    },
    /**
     * @description: 每个item的调度策略
     * @param {*} item
     * @return {*}
     */
    itemScheduleStrategy(item) {
      if (
        item.inRedeploy &&
        Array.isArray(item.redeployScheduleParams) &&
        item.redeployScheduleParams.length > 0 &&
        item.redeployScheduleParams[0]
      ) {
        // 处于重新部署时
        return item.redeployScheduleParams[0]
      }
      return item.scheduleStrategy
    },
    /**
     * @description: 修改调度策略成功回调
     * @param {*} val 返回值
     * @return {*}
     */
    simpleEditScheduleCallback(val) {
      if (this.scheduleDialogIndex >= 0) {
        this.$set(
          this.list[this.scheduleDialogIndex],
          'redeployScheduleParams',
          val
        )
      }
    },
    /**
     * @description: 修改调度策略
     * @param {*} item
     * @return {*}
     */
    scheduleStrategyClick(item, index) {
      const scheduleStrategyFormat = {} // 调度策略格式化
      this.scheduleStrategyAll.forEach((strategy) => {
        if (item.scheduleStrategy) {
          scheduleStrategyFormat[strategy.value] =
            item.scheduleStrategy[strategy.value]
        }
      })
      const itemScheduleStrategy = this.itemScheduleStrategy(item)
      this.scheduleDialogIndex = index
      this.scheduleDialogInfo = {
        serviceId: item.svcId, // serviceId
        serviceName: item.svcName, // 服务名
        serviceStatus: item.status, // 微服务状态
        id: item.scheduleStrategy ? item.scheduleStrategy.id : '', // 策略id
        scheduleStrategy: scheduleStrategyFormat, // 调度策略
        businessScene: itemScheduleStrategy
          ? itemScheduleStrategy.businessScene
          : '', // 业务场景
        serviceModel: itemScheduleStrategy
          ? itemScheduleStrategy.serviceModel
          : '', // 服务模型调度
        intelligentScheduleActive: item.scheduleStrategy
          ? item.scheduleStrategy.intelligentScheduleActive
          : '0', // 智能决策
        intelligentDuration: item.scheduleStrategy
          ? item.scheduleStrategy.intelligentDuration
          : '' // 智能决策周期
      }
      this.showScheduleDialog = true // 显示弹窗
    },
    /**
     * @description: 重新部署-确定
     * @param {*} index
     * @return {*}
     */
    async redeployConfirm(index) {
      this.$set(this.list[index], 'redeployBtnLoading', true)
      try {
        const scheduleStrategy = Object.assign(
          {},
          this.list[index].scheduleStrategy || {}
        )
        scheduleStrategy['svcId'] = scheduleStrategy['serviceId']
        delete scheduleStrategy.id
        delete scheduleStrategy.algDeployClusterInfos
        let scheduleParams = [scheduleStrategy]
        if (
          Array.isArray(this.list[index].redeployScheduleParams) &&
          this.list[index].redeployScheduleParams.length > 0
        ) {
          scheduleParams = this.list[index].redeployScheduleParams
        }
        await addScheduleStrategy(scheduleParams)
        await microServiceOperation({
          svcId: this.list[index].svcId,
          operationType: 'reDistribute'
        })
        this.list[index].redeployBtnLoading = false
        this.$set(this.list[index], 'inRedeploy', false)
        this.$message.success('重新部署成功')
        this.getList()
      } catch (err) {
        console.log(err)
        this.list[index].redeployBtnLoading = false
      }
    },
    /**
     * @description: 重新部署-取消
     * @param {*} index
     * @return {*}
     */
    redeployCancel(index) {
      this.$set(this.list[index], 'inRedeploy', false)
      this.$delete(this.list[index], 'redeployScheduleParams')
    },
    /**
     * @description: 重新部署
     * @param {*} index
     * @return {*}
     */
    redeployClick(index) {
      this.$set(this.list[index], 'inRedeploy', true)
    },
    /**
     * @description: 删除微服务
     * @param {*} row
     * @return {*}
     */
    deleteMicSvc(row) {
      if (
        row.category === 'BIGDATA' &&
        (row.status === '1' || row.status === '3')
      ) {
        this.$message.error('该状态下禁止删除微服务！')
        return false
      }
      this.$confirm('您确认要删除该微服务吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        closeOnClickModal: false,
        type: 'warning'
      }).then(() => {
        // 请求
        microServiceOperation({
          svcId: row.svcId,
          operationType: 'delete'
        }).then((res) => {
          this.$message.success('删除成功')
          if (this.list.length === 1) {
            // 当前页只有一条数据时 删除完刷新上一页数据
            this.pageNum = Math.max(this.pageNum - 1, 1)
          }
          this.getList() // 请求数据
        })
      })
    },
    /**
     * @description: 切换暂停及启动状态
     * @param {*} row
     * @return {*}
     */
    switchStatus(row) {
      this.$confirm(
        '您确认要' + (row.status === '1' ? '暂停' : '恢复') + '该微服务吗？',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          closeOnClickModal: false,
          type: 'warning'
        }
      ).then(() => {
        // 请求
        microServiceOperation({
          svcId: row.svcId,
          operationType: row.status === '1' ? 'suspend' : 'resume'
        }).then((res) => {
          this.$message.success(row.status === '1' ? '暂停成功' : '启动成功')
          this.getList() // 请求数据
        })
      })
    },
    /**
     * @description: size变化
     * @param {*} size
     * @return {*}
     */
    sizeChange(size) {
      this.pageSize = size
      this.pageNum = 1
      this.getList(false) // 请求数据
    },
    /**
     * @description: 切换页码
     * @param {*} pageNum
     * @return {*}
     */
    changePage(pageNum) {
      this.pageNum = pageNum
      this.getList(false) // 请求数据
    },
    /**
     * @description: 重置
     * @return {*}
     */
    resetClick() {
      this.applicationName = ''
      this.serviceName = ''
      this.pageNum = 1 // 第一页
      this.getList(false) // 请求数据
    },
    /**
     * @description: 查询
     * @return {*}
     */
    queryClick() {
      this.pageNum = 1
      this.getList(false) // 请求数据
    },
    /**
     * @description: 获取多集群信息
     * @return {*}
     */
    getMultiClusterInfo() {
      const svcIds = this.list.map((item) => {
        return item.svcId
      })
      getClusterScaleInfos({
        svcIds: svcIds
      }).then((res) => {
        const keys = res.data ? Object.keys(res.data) : []
        if (keys.length > 0) {
          let deploySuccessAll = true
          this.list.forEach((element, index) => {
            const scaleInfos = res.data[element.svcId] // 微服务对应的扩缩容集群信息
            if (
              keys.includes(element.svcId) &&
              Array.isArray(scaleInfos) &&
              scaleInfos.length > 0
            ) {
              for (const scaleInfo of scaleInfos) {
                // 每个集群
                if (
                  Array.isArray(scaleInfo.algDeployClusterInfos) &&
                  scaleInfo.algDeployClusterInfos.length > 0
                ) {
                  // 每个集群的算法分析结果
                  const vmScaleStragetyStr =
                    element.clusterAndAlgs.length > 0
                      ? element.clusterAndAlgs[0].vmScaleStragetyStr
                      : '不配置' // 集群的虚机扩缩容暂时使用默认部署的虚机扩缩容策略
                  let provider = scaleInfo.recommendCloud // 算法选择的云商
                  let clusterName = '' // 算法选择的集群
                  const recommendCluster = scaleInfo.algDeployClusterInfos.find(
                    (item) => {
                      // 找到多集群信息中有用的数据，即算法推荐的数据
                      return (
                        item.providerName === scaleInfo.recommendCloud &&
                        item.accountName === scaleInfo.recommendAccountName
                      )
                    }
                  ) // 匹配出已选择的云商集群
                  if (recommendCluster) {
                    // 存在
                    provider = scaleInfo.recommendCloud
                    clusterName = recommendCluster.name
                  } else {
                    // 不存在
                    provider = scaleInfo.algDeployClusterInfos[0].providerName
                    clusterName = scaleInfo.algDeployClusterInfos[0].name
                  }
                  const providerChn = this.getCloudProviderChn(provider) // 云商中文
                  deploySuccessAll =
                    deploySuccessAll && scaleInfo.svcDeploySuccess // 是否都部署成功
                  // 找出原始部署集群数据
                  const originalClusterAndAlgs = element.clusterAndAlgs.filter(
                    (item) => {
                      return item.original
                    }
                  )
                  // 插入找到的数据
                  originalClusterAndAlgs.push({
                    original: false,
                    providerImg: getCloudProviderImg(
                      this.$store.state.app.cloudVendors,
                      providerChn
                    ), // 云商icon
                    providerChn, // 云商名称
                    clusterName, // 集群名称
                    deployed: scaleInfo.svcDeploySuccess, // 已部署
                    vmScaleStragetyStr: vmScaleStragetyStr,
                    algResults: {
                      recommendCloud: scaleInfo.recommendCloud,
                      userChooseCloud: scaleInfo.recommendCloud, // 用户选择 默认使用推荐
                      recommendAccountName: scaleInfo.recommendAccountName,
                      userChooseAccountName: scaleInfo.recommendAccountName, // 用户选择 默认使用推荐
                      algDeployClusterInfos: scaleInfo.algDeployClusterInfos
                    } // 算法分析结果
                  })
                  element.clusterAndAlgs = originalClusterAndAlgs
                }
              }
            }
          })
          if (!deploySuccessAll) {
            // 没有全部部署成功
            this.scaleClustersTimer && clearTimeout(this.scaleClustersTimer)
            this.scaleClustersTimer = setTimeout(() => {
              this.getMultiClusterInfo()
            }, 15 * 1000) // 使用定时器刷新信息
          }
        }
      })
    },
    /**
     * @description: 处理list
     * @param {*} list
     * @param {*} needMergeOriginalParams 是否需要合并list原有参数，主要为重新部署相关参数：inRedeploy、redeployScheduleParams、redeployBtnLoading
     * @return {*}
     */
    handleListData(list, needMergeOriginalParams) {
      const newList = list.map((element) => {
        let vmScaleStragetyStr = '不配置'
        if (Array.isArray(element.scaleStrategy)) {
          // scaleStrategys排序
          element.scaleStrategy.sort((x, y) => {
            return (
              Object.keys(STRATEGY_SCALE_TYPE).indexOf(x.scaleType) -
              Object.keys(STRATEGY_SCALE_TYPE).indexOf(y.scaleType)
            )
          })
          // 临时策略：查找虚机扩缩容策略是否配置，用于多集群下虚机扩缩容策略配置与否展示
          const vmStrategyFind = element.scaleStrategy.find((stragety) => {
            return stragety.scaleType === 'vm'
          })
          if (
            !vmStrategyFind ||
            vmStrategyFind.strategyParam.includes(this.scaleStrategyNoneStr)
          ) {
            vmScaleStragetyStr = '不配置'
          }
        }
        // 格式化云商集群信息与算法分析结果
        const clusterAndAlgs = []
        if (Array.isArray(element.clusterInfos)) {
          for (const provider of element.clusterInfos) {
            const providerChn = this.getCloudProviderChn(provider.manufacturer) // 云商中文
            for (const clusterName of provider.clusterNames) {
              if (clusterName) {
                clusterAndAlgs.push({
                  original: true,
                  providerImg: getCloudProviderImg(
                    this.$store.state.app.cloudVendors,
                    providerChn
                  ), // 云商icon
                  providerChn, // 云商名称
                  clusterName, // 集群名称
                  deployed: true, // 已部署
                  vmScaleStragetyStr: vmScaleStragetyStr,
                  algResults: {
                    // 算法分析结果
                    recommendCloud: element.scheduleStrategy
                      ? element.scheduleStrategy.recommendCloud
                      : '', // 推荐的云商
                    userChooseCloud: element.scheduleStrategy
                      ? element.scheduleStrategy.userChooseCloud
                      : '', // 用户已选择的云商
                    recommendAccountName: element.scheduleStrategy
                      ? element.scheduleStrategy.recommendAccountName
                      : '', // 推荐云商的账号
                    userChooseAccountName: element.scheduleStrategy
                      ? element.scheduleStrategy.userChooseAccountName
                      : '', // 用户已选择的云商账号
                    algDeployClusterInfos:
                      element.scheduleStrategy &&
                      Array.isArray(
                        element.scheduleStrategy.algDeployClusterInfos
                      )
                        ? element.scheduleStrategy.algDeployClusterInfos
                        : []
                  }
                })
              }
            }
          }
        }
        element.clusterAndAlgs = clusterAndAlgs
        element.activeAlgIndex = -1
        return element
      })
      if (needMergeOriginalParams) {
        this.list.forEach((element) => {
          if (element.inRedeploy) {
            const newIndex = newList.findIndex((item) => {
              return item.svcId === element.svcId
            })
            if (newIndex > -1) {
              newList[newIndex].inRedeploy = element.inRedeploy
              newList[newIndex].redeployScheduleParams =
                element.redeployScheduleParams
              newList[newIndex].redeployBtnLoading = element.redeployBtnLoading
            }
          }
        })
      }
      this.list = newList
      this.getMultiClusterInfo()

      // 是否部分应用处于loading态
      const someInloading = this.list.some((element) => {
        // 启动中 or 删除中
        return element.status === '3' || element.status === '4'
      })
      if (someInloading) {
        // 部分应用处于loading
        // 新建定时器
        this.timerRefresh = setTimeout(() => {
          // 刷新
          this.getList()
        }, 5 * 1000)
      }
    },
    /**
     * @description: 加载数据
     * @return {*}
     */
    getList(needMergeOriginalParams = true) {
      // 清除刷新定时器
      this.clearTimerAndReq()
      abortController = new AbortController()
      // 请求
      getMicroServiceList(
        {
          applicationName: this.applicationName,
          serviceName: this.serviceName,
          pageSize: this.pageSize,
          pageNum: this.pageNum
        },
        abortController.signal
      ).then((res) => {
        if (res.data) {
          this.totalSize = res.data.totalSize
          const list = Array.isArray(res.data.data) ? res.data.data : []
          this.handleListData(list, needMergeOriginalParams)
        } else {
          // 数据为空处理
          this.totalCount = 0
          this.list = []
        }
      })
    },
    /**
     * @description: 初始化数据
     * @return {*}
     */
    initPageData() {
      this.loading = true
      this.pageNum = 1
      this.getList(false)
    }
  }
}
</script>

<style lang="less" scoped>
@import "@/assets/css/common.less";
.policy-deployment-container {
  .header {
    padding: 0px 25px;
    .name {
      .textStyle(14px , 400, #4a4a4a);
      line-height: 20px;
    }
  }
  .main {
    padding: 20px 25px;

    /deep/ .el-button--text.el-button--mini {
      padding: 4px 0;
      font-size: 14px;
    }

    .service {
      background: #eaeff4;
      border-radius: 6px;
      box-sizing: border-box;
      padding: 10px 20px 20px;
      margin-bottom: 20px;

      &.active {
        background: linear-gradient(213deg, #00c4ff 0%, #0091ff 100%);

        .top .title {
          color: #ffffff;
        }
        .top .options .icon {
          color: #ffffff;
        }
        .top .options .line {
          background-color: #ffffff;
        }
        .top .options .detail-btn {
          color: #ffffff;
        }
      }

      .top {
        display: flex;
        align-items: center;
        .title {
          .textStyle(16px , 600, #4a4a4a);
          line-height: 22px;
        }
        .arch {
          margin: 0 0 0 5px;
          display: inline-block;
          padding: 0 10px;
          box-sizing: border-box;
          height: 24px;
          line-height: 22px;
          background: rgba(255, 255, 255, 0.8);
          border-radius: 12px;
          border: 1px solid #027dec;
          .textStyle(14px, 500, #027dec);
        }
        .status {
          margin-left: 20px;
        }
        .options {
          margin-left: auto;
          display: flex;
          align-items: center;
          .icon {
            color: #3fa2f7;
            margin-left: 6px;
            font-size: 15px;
            cursor: pointer;
          }
          .line {
            width: 2px;
            height: 12px;
            background-color: #b9b9b9;
            margin: 0 8px;
          }
        }
      }

      .basic {
        margin-top: 10px;
        background: #ffffff;
        border-radius: 7px;
        padding: 15px 20px;
        box-sizing: border-box;
        .basic-item {
          width: 22.5%;
          display: inline-flex;
          align-items: center;
          &.special {
            width: 32.5%;
          }
          .subtitle {
            min-width: 60px;
            .textStyle(14px , 400, #C3C3C3);
            margin-right: 20px;
            text-align: center;
          }
          .subcontent {
            .textStyle(14px , 400, #4a4a4a);
          }
          .path {
            .textStyle(14px , 400, #4a4a4a);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            margin-right: 10px;
          }
        }
      }

      .policys {
        margin-top: 20px;
        background: #ffffff;
        border-radius: 7px;
        padding: 20px 20px 10px;
        box-sizing: border-box;
        display: flex;
        color: #4a4a4a;

        .subtitle {
          min-width: 60px;
          .textStyle(14px , 400, #C3C3C3);
          margin-right: 20px;
          text-align: center;
          line-height: 20px;
        }

        .schedule {
          // flex: 4;
          flex: 1;
          display: flex;
          flex-direction: column;

          .column {
            display: flex;
            align-items: flex-start;

            &.scene {
              margin-bottom: 12px;
              padding-bottom: 12px;
              border-bottom: 1px solid #e9e9e9;
              .subcontent {
                .textStyle(14px, 500, #027dec);
                line-height: 20px;
              }
            }
          }

          .sublist {
            display: flex;
            flex-wrap: wrap;
            align-items: center;

            .line {
              width: 1px;
              height: 13px;
              background-color: #d8d8d8;
              margin: 0 10px;
              margin-bottom: 10px;
            }
            .subitem {
              .textStyle(14px, 500, #4a4a4a);
              margin-bottom: 10px;
              line-height: 20px;
            }
          }
        }
        .scale {
          // flex: 5;
          width: 55%;

          .column {
            display: flex;
            align-items: center;
            margin-bottom: 12px;
            .subcontent {
              .textStyle(14px , 400, #4a4a4a);
              margin-right: 20px;
              &.content2 {
                margin-right: 50px;
              }
            }
            &.wrap {
              flex-wrap: wrap;
            }
          }
        }
        .pline {
          display: inline-block;
          width: 1px;
          height: 80px;
          margin: 0 30px;
          box-sizing: border-box;
          background-color: #e9e9e9;
        }
      }

      .intelligent {
        margin-top: 20px;
        background: #ffffff;
        border-radius: 7px;
        padding: 20px;
        box-sizing: border-box;
        display: flex;
        color: #4a4a4a;
        .title {
          .textStyle(16px, 600, #4a4a4a);
          line-height: 22px;
          margin-bottom: 15px;
        }
        .left {
          flex: 1;
          .column {
            display: flex;
            align-items: center;
            margin-bottom: 10px;
            .subtitle {
              .textStyle(14px, 400, #4a4a4a);
              margin-right: 10px;
            }
          }
        }
        .right {
          width: 55%;

          .decision-table {
            .el-table::before {
              background-color: #e9e9e9;
            }
            /deep/ .listHeaderCell {
              background: #f3f3f3;
              height: 36px;
              padding: 0;
              box-sizing: border-box;
              &:first-child {
                padding-left: 20px;
              }
            }

            /deep/ .el-table__body {
              .el-table__row td {
                height: 36px;
                padding: 0;
                &:first-child {
                  padding-left: 20px;
                }
              }
            }
            /deep/ .el-table tbody tr:hover > .el-table__cell {
              background: #eaeaea;
            }
          }
        }
        .pline {
          display: inline-block;
          width: 1px;
          margin: 0 30px;
          box-sizing: border-box;
          background-color: #e9e9e9;
        }
      }

      .clusters {
        margin-top: 20px;
        background: #ffffff;
        border-radius: 7px;
        padding: 20px;
        box-sizing: border-box;
        color: #4a4a4a;
        position: relative;
        .title {
          .textStyle(16px, 600, #4a4a4a);
          line-height: 22px;
          margin-bottom: 15px;
        }
        .expand {
          position: absolute;
          right: 30px;
          bottom: 20px;
        }
        .cluster-wrapper {
          display: flex;
          flex-direction: row;
          align-items: center;

          .cluster {
            display: flex;
            flex-direction: column;
            align-items: center;
            margin-right: 50px;
            cursor: pointer;

            &.unable {
              cursor: no-drop;
            }

            .img-wrapper {
              box-sizing: border-box;
              width: 90px;
              height: 90px;
              background: #ffffff;
              box-shadow: 2px 2px 4px -4px rgba(201, 197, 218, 0.47);
              border-radius: 2px;
              border: 1px solid #d6d6d6;
              text-align: center;
              &.unable {
                background: #f2f2f2;
                border: 1px solid #f0f0f0;
              }

              .img {
                margin-top: 14px;
                width: 65px;
              }
            }
            .name {
              .textStyle(14px, 500, #C3C3C3);
              line-height: 20px;

              &.provider {
                color: #4a4a4a;
                margin-top: 10px;
              }
            }
          }
        }
      }

      .alg-results-wrapper {
        margin-top: 20px;
      }
    }
  }
}
</style>
